Type CB3DModel

	Field Skele:CalCoreSkeleton
	Field CoreModel:CalCoreModel
	Field CModel:CalModel		
	Field B3dModel:TMesh	
	Field Meshes:TList
	Field Materials:TList
	Field Anims:TList
	Field MAnims:TList
	Field cal_renderer:CalRenderer
	Field isloaded:Byte = False
	Field rebuild:Byte = False
	Field SkeletonLoaded:Byte = False
	Field isanim:Byte = False
	Field SkeleFile:String
	Field SkeleName:String

	Method New()
		
		B3dModel = TMesh.CreateMesh()
		Meshes = New TList
		Anims = New TList
		MAnims = New TList
		Materials = New TList
		CoreModel = New CalCoreModel
		'MeshFileList = New StringList
	End Method

	Method SetSkeleton(skel:CalCoreSkeleton)
		Skele = skel
		CoreModel.setCoreSkeleton(Skele)
	End Method

	Method Animate(id:Int=1)
		CModel.getMixer().blendCycle(id,1,0)
	End Method
	
	Method StopAnimation(id:Int=1)
		CModel.getMixer().clearCycle(id,0)
	End Method
	
	Method StopMorphAnimation(id:Int=1)
		CModel.getMorphTargetMixer().clear(id,0)
	End Method
	
	Method AnimateMorph(id:Int=1)
		CModel.getMorphTargetMixer().blend(id,1,0)
	End Method

	Method AddAnim:CB3DAnimation(anm:CalCoreAnimation)
		'If Skele = Null Then Return


		If anm <> Null Then
			Local c3db3da:CB3DAnimation = New CB3DAnimation
			c3db3da.id = CoreModel.addCoreAnimation(anm)
			DebugLog "ANIM ID: "+c3db3da.id
			c3db3da.parent = Self
			Anims.AddLast(c3db3da)
			Return c3db3da
		EndIf
		Return Null
		
	End Method

	Method AddMorphAnim:CB3DMAnimation(anm:CalCoreAnimatedMorph)
		'If Skele = Null Then Return


		If anm <> Null Then
			Local c3db3da:CB3DMAnimation = New CB3DMAnimation
			c3db3da.id = CoreModel.addCoreAnimatedMorph(anm)
			DebugLog "MORPH ID: "+c3db3da.id
			c3db3da.parent = Self
			MAnims.AddLast(c3db3da)
			Return c3db3da
		EndIf
		Return Null
		
	End Method


	Method AddMaterial:CB3DMaterial(cmat:CalCoreMaterial,matid:Int,texdir:String="")
	Local mat:CB3DMaterial
	
		For Local mmat:CB3DMaterial = EachIn Materials
		
			If mmat.matid = matid Then
				mat = mmat
				
				haveid = True
				Exit
			EndIf
		
		Next
		If mat = Null Then
			mat:CB3DMaterial = New CB3DMaterial
			mat.Cmat = cmat
			mat.matid = matid
			CoreModel.addCoreMaterial(cmat)
		EndIf
		DebugLog "Created Material: "+matid
		
		DebugLog "Mapcount: "+cmat.getMapCount()
		For Local i:Int = 0 To cmat.getMapCount()-1
			Local cimg:CB3DTexture = New CB3DTexture
			cimg.id = i
			
			Local fname:String = cmat.getMapFilename(i)
			Local nfname:String = StripDir(StripExt(fname))
			
			DebugLog "Fetch: "+cmat.getMapFilename(i)
			cimg.name = nfname
			'Print "Get "+
			cimg.tex = LoadTexture(texdir+cmat.getMapFilename(i))
			If cimg.tex = Null Then
				DebugLog "texture was null"
			EndIf
			mat.AddMap(cimg,i)
			
		Next
		Materials.AddLast(mat)
		mat.isloaded = True
		Return mat
	End Method


	Method GetMaterial:CB3DMaterial(index:Int)
	
		For Local mat:CB3DMaterial = EachIn Materials
		
			If mat.matid = index Then

				'If mat.isloaded = True Then
					'if material is loaded then assign the material to our b3d surface
				'	PaintMaterial(ii:Int,brush:TBrush)
				'Endif
				'DebugLog "index: "+index
				Return mat
				
			EndIf
		
		Next
			
		Return Null
	
	End Method

	Method AddMesh:CB3DMesh(msh:CalCoreMesh)
		
	
			If msh <> Null Then
				
				Local c3db3dm:CB3DMesh = New CB3DMesh
				c3db3dm.MeshID = CoreModel.addCoreMesh(msh)
				DebugLog "Added: "+c3db3dm.MeshID
				c3db3dm.CMesh = msh
				If c3db3dm.B3dMesh <> Null Then FreeEntity(c3db3dm.B3dMesh)
				c3db3dm.B3dMesh = TMesh.CreateMesh(B3dModel)
				'c3db3dm.B3dMesh.anim = 2
				c3db3dm.parent = Self
				
				'iterate through submeshes to retrieve material ids
				For Local i:Int = 0 To c3db3dm.CMesh.getCoreSubmeshCount()-1
				
					Local smesh:CalCoreSubmesh = c3db3dm.CMesh.getCoreSubmesh(i)
					If smesh <> Null Then
					
						Local matid:Int = smesh.getCoreMaterialThreadId()
						'see if we have the id
						Local haveid:Byte = False
						For Local mat:CB3DMaterial = EachIn Materials
						
							If mat.matid = matid Then
								haveid = True
								Exit
							EndIf
						
						Next
						If haveid = False Then
							Local cmat:CB3DMaterial = New CB3DMaterial
							cmat.matid = matid
							Materials.AddLast(cmat)
						EndIf
					
					EndIf
				
				Next
				
				Meshes.AddLast(c3db3dm)
				Return c3db3dm
			EndIf
			Return Null
	End Method


	Method Build()
		If CoreModel.getCoreSkeleton() = Null Then
			DebugLog "Core Skeleton is null!"
			Return
		EndIf
		CoreModel.getCoreSkeleton().calculateBoundingBoxes(CoreModel)
		
		For Local mat:CB3DMaterial = EachIn Materials
			'Haxx...
			CoreModel.createCoreMaterialThread(mat.matid)
			CoreModel.setCoreMaterialId(mat.matid, 0, mat.matid)		
		Next			
		CModel = CoreModel.makemodel()
		
		For Local cb3d:CB3DMesh = EachIn Meshes
			CModel.attachMesh(cb3d.MeshID)
		Next
		
	
		
		'For Local anm:CalCoreAnimation = Eachin Anims
		'	CModel.
		'Next
		If CModel <> Null Then
			DebugLog "Have Cmodel"
		EndIf
		If isanim = True Then
			'CModel.getMixer().blendCycle(0,1,0)
		EndIf
		cal_renderer = CModel.getRenderer()
		cal_renderer.beginRendering()
			
		Local mc:Int = cal_renderer.getMeshCount()	
		DebugLog "Mesh Count: "+mc
		For Local i:Int = 0 To mc	
			
			For cb3d = EachIn Meshes
				'If cb3d.B3dMesh <> Null Then cb3d.B3dMesh.FreeEntity()
				'cb3d.B3dMesh = TMesh.CreateMesh(B3dModel)
				'cb3d.B3dMesh.anim = 2	
				If cb3d.MeshID = i Then
					DebugLog "Got Mesh: "+i
					'cal_renderer.selectMeshSubmesh(mc,i)
					Local submeshCount:Int = cal_renderer.getSubmeshCount(i)
					DebugLog "NOF: Submeshes "+submeshCount
					'cb3d.surf = New TSurface[0]
					For Local ii:Int = 0 To submeshCount-1
					
						cal_renderer.selectMeshSubmesh(cb3d.MeshID,ii)
						
						Local vertexCount:Int = cal_renderer.getVertexCount()
						Local faceCount:Int = cal_renderer.getFaceCount()
						
						DebugLog "Verts: "+vertexCount+" Faces"+faceCount
						


						Local faces:Short[] = New Short[faceCount*3]
						Local vertices:Float[] = New Float[vertexCount*3]						
						cal_renderer.getVertices(vertices)	
						cal_renderer.getFaces(faces)
						cb3d.Build(ii,vertices,faces)
						'Local smesh:CalSubmesh = CModel.getMesh(cb3d.MeshID).getSubmesh(ii)
						'Local brush:Cal3dB3dMaterial = GetMaterial(smesh.getCoreMaterialId)
						'If brush <> Null Then
						'	cb3d.PaintMaterial(ii,brush.B3dBrush)
						'EndIf
						
						
										
						
					Next
					

					
				
				
				EndIf
			
			Next
		
		Next
		cal_renderer.endRendering()
		
	
	End Method

	Method Destroy()
		
		For Local cb3d:CB3DMesh = EachIn Meshes
			If cb3d.B3dMesh <> Null Then FreeEntity(cb3d.B3dMesh)
		Next
		For Local mat:CB3DMaterial = EachIn Materials
			For Local ctex:CB3DTexture = EachIn mat.maps
				FreeTexture(ctex.tex)
			Next
			FreeBrush(mat.B3dBrush)	
		Next
		ClearList(Meshes)
		ClearList(Materials)
		ClearList(Anims)
		ClearList(MAnims)
		
	End Method


	Method Update:Int(d:Float)
			If CModel = Null Then Return -1
			CModel.update(d)
			cal_renderer.beginRendering()
				Local mc:Int = cal_renderer.getMeshCount()
				For Local i:Int = 0 To mc	
					For Local cb3d:CB3DMesh = EachIn Meshes
						If cb3d.MeshID = i Then
							Local submeshCount:Int = cal_renderer.getSubmeshCount(i)
							
							For Local ii:Int = 0 To submeshCount-1
								cal_renderer.selectMeshSubmesh(cb3d.MeshID,ii)
								Local vertexCount:Int = cal_renderer.getVertexCount()
								'Local faceCount:Int = cal_renderer.getFaceCount()
	
								
								Local vertices:Float[] = New Float[vertexCount*3]
								Local normals:Float[] = New Float[vertexCount*3]
								Local texcoords:Float[] = New Float[vertexCount*2]
						
								cal_renderer.getVertices(vertices)	
								cal_renderer.getNormals(normals)
								Local smesh:CalCoreSubmesh = CoreModel.getCoreMesh(cb3d.MeshID).getCoreSubmesh(ii)
								cal_renderer.getTextureCoordinates(smesh.getCoreMaterialThreadId(),texcoords)
								
							'	cb3d.surf[ii].reset_vbo = -1
								
							'	Print "Get Brush: "+smesh.getCoreMaterialThreadId()
								Local brush:CB3DMaterial = GetMaterial(smesh.getCoreMaterialThreadId())
								If brush <> Null Then
									PaintEntity(cb3d.B3dMesh,brush.B3dBrush)
									'cb3d.PaintMaterial(ii,brush.B3dBrush)
								EndIf								
								'Print "MAT: "+cal_renderer.m_selectedSubmesh.m_coreMaterialId
								'If cal_renderer.m_selectedSubmesh.m_coreMaterialId > -1 then
									'cal_renderer.getTextureCoordinates(0,texcoords,3)
								
									'cb3d.Update(ii,vertices,faces)
								'Else
									'cb3d.Update(ii,vertices,faces)
								'Endif
								'cb3d.surf[ii].ClearSurface(True,True,False)
								cb3d.Update(ii,vertices,normals,texcoords)
								
							Next
						EndIf
					Next
				Next
			cal_renderer.endRendering()

	End Method	


End Type
